package a09_贪心算法;

import java.util.Arrays;

/**
 * @author: fosss
 * Date: 2023/8/21
 * Time: 18:09
 * Description:
 * 给定一个整数数组 A，我们只能用以下方法修改该数组：我们选择某个索引 i 并将 A[i] 替换为 -A[i]，然后总共重复这个过程 K 次。（我们可以多次选择同
 * 一个索引 i。）以这种方式修改数组后，返回数组可能的最大和。
 * 示例 1：
 * 输入：A = [4,2,3], K = 1
 * 输出：5
 * 解释：选择索引 (1,) ，然后 A 变为 [4,-2,3]。
 * 示例 2：
 * 输入：A = [3,-1,0,2], K = 3
 * 输出：6
 * 解释：选择索引 (1, 2, 2) ，然后 A 变为 [3,1,0,2]。
 * 示例 3：
 * 输入：A = [2,-3,-1,5,-4], K = 2
 * 输出：13
 * 解释：选择索引 (1, 4) ，然后 A 变为 [2,3,-1,5,4]。
 * 提示：
 * 1 <= A.length <= 10000
 * 1 <= K <= 10000
 * -100 <= A[i] <= 100
 */
public class B07_K次取反后最大化的数组和 {

    /**
     * 局部最优：k不为0时将尽可能地将负数转为相反值（正数），如果k此时还不等于0，如果是偶数，则不需要处理（一个数反偶数次不变），否则将最小的数转为相反数
     */
    public int largestSumAfterKNegations(int[] nums, int k) {
        //先排序
        Arrays.sort(nums);
        //k不为0时，挨个将负数反转
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] < 0 && k > 0) {
                nums[i] = -nums[i];
                k--;
            }
        }
        //如果k不为0，则此时数组中所有元素都为正数。还需要对小的整数进行反转。注意只对最小的那个反转就行
        if (k > 0) {
            Arrays.sort(nums);
            //k为偶数，不用处理
            //不为偶数，将最小的那个正数转为相反值
            if (k % 2 != 0) {
                nums[0] = -nums[0];
            }
        }
        //计算和
        int sum = 0;
        for (int num : nums) {
            sum += num;
        }
        return sum;
    }
}
